﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Tomahawk.Runtime.Debug.Exceptions;

namespace Tomahawk.Runtime.Canvas
{
    /// <summary>
    /// Provides an optimized interface for 2D Sprite rendering
    /// </summary>
    public class CanvasManager
    {   
        private GraphicsDevice graphicsDevice;

        /// <summary>
        /// Constructor
        /// </summary>
        public CanvasManager(GraphicsDevice graphicsDevice)
        {
            //stores the graphics device
            this.graphicsDevice = graphicsDevice;

            //create the renderers collection
            this.canvasRenderers = new SortedList<int, ICanvasPrimitiveRenderer>();

            //instance the default sprite groups
            this.createDefaultPrimitiveRenderers();
        }
        
        #region "SpriteGroups management"

        /// <summary>
        /// List of primitive renderers defined. Sorted by render priority
        /// </summary>
        SortedList<int, ICanvasPrimitiveRenderer> canvasRenderers;

        /// <summary>
        /// Add a spriteGroup to the list
        /// </summary>
        public void RegisterCanvasPrimitiveRenderer(ICanvasPrimitiveRenderer newCanvasRenderer, int renderPriority)
        {
            //add to the array
            canvasRenderers.Add(renderPriority, newCanvasRenderer);
            //initialize it
            newCanvasRenderer.Initialize(this.graphicsDevice);
        }

        /// <summary>
        /// Empty the canvas primitives renderers list
        /// </summary>
        public void ClearCanvasPrimitiveGroups()
        {
            foreach (ICanvasPrimitiveRenderer renderer in this.canvasRenderers.Values)
            {
                //TODO: Destroy sprite group
            }
            //empty the list
            this.canvasRenderers.Clear();
        }

        #region "Tomahawk's default primitive renderers"

        private Sprite.UISpriteRenderer cpr_UISprites;

        /// <summary>
        /// Default primitive renderer for UISprites
        /// </summary>
        public Sprite.UISpriteRenderer CPR_UISprites
        {
            get { return this.cpr_UISprites; }
        }

        /// <summary>
        /// Create defaults sprite groups
        /// </summary>
        private void createDefaultPrimitiveRenderers()
        {
            //renderer for standar GUI textured tiles
            //(No special shader effects, single texture, different textures per each sprite)
            cpr_UISprites = new Sprite.UISpriteRenderer();
            this.RegisterCanvasPrimitiveRenderer(cpr_UISprites, 100);
        }

        #endregion

        #endregion

        /// <summary>
        /// Render all SpriteGroups in an appropiate order
        /// </summary>
        internal void Render()
        {
            //traverse the SpriteGroup array in priority order and 
            //render their sprites
            foreach (ICanvasPrimitiveRenderer sprGrp in this.canvasRenderers.Values)
            {
                //render
                sprGrp.Render();
            }
        }

        #region "Exceptions"

        /// <summary>
        /// Base exception for all canvas subsystem exceptions
        /// </summary>
        public class CanvasException : Debug.Exceptions.XEngineException
        {
            public CanvasException(ExceptionSeverity severity, String msg) : base (severity, msg, null)
            {
            }
        }

        #endregion

    }

}
